package view.panels;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.InputVerifier;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

import model.Actions;
import model.ElementAction;
import utilities.EPatterns;
import utilities.PatternsInfoLoader;
import view.frames.ClassesMapperFrame;

/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/

public class ElementsMappingPanel extends javax.swing.JPanel {
	
	
	/**
	 * 
	 */
	private EPatterns pattern = EPatterns.AbstractFactory;
	private Vector<String> elements = new Vector<String>();
	private Actions actions;

	/**
	 * GUI
	 */
	private static final long serialVersionUID = 1L;
	private Vector<JLabel> jLabels = new Vector<JLabel>();
	private Vector<JComboBox<String>> jComboBoxes = new Vector<JComboBox<String>>();
	private Vector<JTextField> jTextFields = new Vector<JTextField>();
	private ClassesMapperFrame parent;

	/**
	* Auto-generated main method to display this 
	* JPanel inside a new JFrame.
	*/
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.getContentPane().add(new ElementsMappingPanel());
		frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
	}
	
	public ElementsMappingPanel() {
		super();
		initGUI();
	}
	
	public ElementsMappingPanel(EPatterns pattern, Actions actions, ClassesMapperFrame parent) {
		super();
		this.pattern = pattern;
		this.actions = actions;
		this.parent = parent;
		elements = (Vector<String>) PatternsInfoLoader.getPatternProperty(pattern, PatternsInfoLoader.PATTERN_ELEMENTS);
		initGUI();
	}
	
	private void initGUI() {
		try {
			GridBagLayout thisLayout = new GridBagLayout();
			this.setBackground(Color.white);
			// Filas
			thisLayout.rowWeights = new double[] {1};
			// Columnas
			thisLayout.columnWeights = new double[] {0.5, 0.5, 0.5};
			thisLayout.columnWidths= new int[] {165, 165, 165};
			this.setLayout(thisLayout);

			int i=0;
			
			for (Enumeration<String> e=elements.elements();e.hasMoreElements();) {
				
				String elem = e.nextElement();
				
				JLabel feedbackLabel = new JLabel();
				feedbackLabel.setName(elem);
				this.add(feedbackLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets((i*60)-350, 10, 0, 0), 0, 0));
				feedbackLabel.setPreferredSize(new java.awt.Dimension(150, 23));
				feedbackLabel.setMaximumSize(new java.awt.Dimension(150, 23));
				feedbackLabel.setMinimumSize(new java.awt.Dimension(150, 23));
				feedbackLabel.setText(elem);
				feedbackLabel.setFont(new java.awt.Font("Curier New",0,12));
				this.jLabels.add(feedbackLabel);
				
				JComboBox<String> jComboBox = new JComboBox<String>();
				jComboBox.setName(elem);
				this.add(jComboBox, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets((i*60)-350, 10, 0, 0), 0, 0));
				jComboBox.insertItemAt("", 0);
				jComboBox.setSelectedIndex(0);
				jComboBox.setPreferredSize(new java.awt.Dimension(150, 23));
				jComboBox.setMaximumSize(new java.awt.Dimension(150, 23));
				jComboBox.setMinimumSize(new java.awt.Dimension(150, 23));
				jComboBox.setFont(new java.awt.Font("Curier New",0,12));
				
				ItemListener itemListener = new ItemListener() {
					@Override
					public void itemStateChanged(ItemEvent arg0) {
						fireChangeItemListener(arg0);
					}		
				};
				
				jComboBox.addItemListener(itemListener);
				
				this.jComboBoxes.add(jComboBox);						
				
				JTextField jTextField = new JTextField();
				jTextField.setName(elem);
				this.add(jTextField, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets((i*60)-350, 10, 0, 0), 0, 0));
				jTextField.setText(elem);
				jTextField.setPreferredSize(new java.awt.Dimension(150, 23));
				jTextField.setMaximumSize(new java.awt.Dimension(150, 23));
				jTextField.setMinimumSize(new java.awt.Dimension(150, 23));
				jTextField.setFont(new java.awt.Font("Curier New",0,12));
				jTextField.setVisible(true);
				jTextField.setInputVerifier(new InputVerifier() {
					    @Override
					    public boolean verify(JComponent input) {
					    	return verifyJTextFieldInput(input);
					    }			
				});
			    this.jTextFields.add(jTextField);
					
				i++;
			}
			
			loadComboBoxesData();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected boolean verifyJTextFieldInput(JComponent input) {

		       String text = ((JTextField) input).getText();
		       if (text.equals("")) {
		    	   parent.errorVisibility(true);
		    	   return false;
		       } else {
		    	   parent.errorVisibility(false);
		    	   return true;
		       }

	}
		
	protected void fireChangeItemListener(ItemEvent arg0) {
		JComboBox<String> modificatedComboBox = ((JComboBox<String>)arg0.getSource());
		
		// Si se elije vacio se pone visible el input text, de lo contrario se oculta
		if (arg0.getItem().equals("")) {
			((JTextField)this.getJTextFieldByName(modificatedComboBox.getName())).setVisible(true);
		} else {
			((JTextField)this.getJTextFieldByName(modificatedComboBox.getName())).setVisible(false);		
		}
		
		for (Enumeration<JComboBox<String>> e=jComboBoxes.elements();e.hasMoreElements();) {
			JComboBox<String> jComboBox = e.nextElement();
			jComboBox.removeItemListener(jComboBox.getItemListeners()[0]);
		}
		
		// Dependiendo de si se seleccciono o deselecciono un elemento se actualizan los combobox
		if (arg0.getStateChange()==ItemEvent.DESELECTED) {
			addElementToComboBoxes(modificatedComboBox, (String) arg0.getItem());
		} else {
			removeElementFromComboBoxes(modificatedComboBox);
		}
		
		for (Enumeration<JComboBox<String>> e=jComboBoxes.elements();e.hasMoreElements();) {
			JComboBox<String> jComboBox = e.nextElement();

			ItemListener itemListener = new ItemListener() {
				@Override
				public void itemStateChanged(ItemEvent arg0) {
					fireChangeItemListener(arg0);
				}		
			};
			
			jComboBox.addItemListener(itemListener);
		}
		
		
		
	}

	/**
	 * Carga los datos iniciales a los combo box
	 */
	private void loadComboBoxesData () {			
		Vector<ElementAction> elementActions = actions.getElementActions();
		for (Enumeration<ElementAction> e=elementActions.elements();e.hasMoreElements();) {
			ElementAction elementAction = e.nextElement();
			addElementToComboBoxes(null,elementAction.getName());
		}		
	}	
	
	/**
	 * Agrega el elemento a todos los combo box, excetp en el combo modificado
	 * @param modificatedComboBox 
	 */
	private void addElementToComboBoxes(JComboBox<String> modificatedComboBox, String element) {
		for (Enumeration<JComboBox<String>> e=jComboBoxes.elements();e.hasMoreElements();) {
			JComboBox<String> jComboBox = e.nextElement();
			if (!(jComboBox.equals(modificatedComboBox))) {		
				String selectedItem = (String) jComboBox.getSelectedItem();
//				jComboBox.insertItemAt(element,jComboBox.getItemCount()-1);
				jComboBox.addItem(element);
				jComboBox.setSelectedItem(selectedItem);
			}
		}	
	}
	
	/**
	 * Borra elemento de todos los combobox, menos del que se selecciono
	 * @param modificatedComboBox
	 */
	private void removeElementFromComboBoxes(JComboBox<String> modificatedComboBox) {	
		for (Enumeration<JComboBox<String>> e=jComboBoxes.elements();e.hasMoreElements();) {
			JComboBox<String> jComboBox = e.nextElement();
			if (!(jComboBox.equals(modificatedComboBox))) {	
				String selectedItem = (String) jComboBox.getSelectedItem();
				jComboBox.removeItem(modificatedComboBox.getSelectedItem());
				jComboBox.setSelectedItem(selectedItem);
			}		
		}	
	}

	/**
	 * Retorna un jtextfield dado un nombre
	 * @param name
	 * @return
	 */
	public JTextField getJTextFieldByName (String name) {
		for (Enumeration<JTextField> e=jTextFields.elements();e.hasMoreElements();) {
			JTextField aux = e.nextElement();
			if (aux.getName().equals(name)) {
				return aux;
			}
		}
		return null;
	}
}
